home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 7 / PC World Interactive 7.iso / program / pasprog.EXE / DISAS386.KOD < prev    next >
Text File  |  1980-01-10  |  45KB  |  1,724 lines

  1. unit disas386;
  2. {
  3.  (c)1994,95 GoRGoN Bilgisayar Yazilim ve Donanim Tic. ltd.
  4.  unit: Disas386
  5.  Desc: Disassembly for DEBUG purposes
  6.  vers: 1.52
  7.  
  8. notes:
  9. - Slow and big!
  10. - Covers 386 instructions only!
  11. - Effective address mode not checked, 16 assumed!
  12. - 32 bit displacements are not signed, implemented as EIP+disp in calls,jmps
  13.                                        implemented as + values in [ebx+AAA...
  14. - math co (387) instructions not implemented.
  15. - sometimes pist (or other strings) may be appended to instruction strings
  16.   (like o1st,o2st..). Do not count on any string var, use and parse dStr if
  17.   necessary.
  18.  
  19. history:
  20.   v1.00 6/94 initial version (BK)
  21.   v1.51 4/95 movzx,movsx bug corrected, some minor optimizations (BK)
  22.   v1.52 9/95 checked format for PS release (BK)
  23. }
  24. {
  25.  
  26.  BU PROGRAM DENEME AMACLI YAZILMISTIR,
  27.  TICARI OLMAMAK KAYDIYLA DILEDIGINIZ GIBI KULLANABILIRSINIZ.
  28. }
  29. {---------------------------------------------------------------------------}
  30. { DEBUG I N T E R F A C E                                                   }
  31. {---------------------------------------------------------------------------}
  32. interface
  33.  
  34. var
  35.    dstr:string;{resulting disassembly string}
  36.  
  37. var
  38.    is : word;{should not be accessed normally}{instruction segment          }
  39.    io : word;{should not be accessed normally}{instruction offset           }
  40.  
  41. const
  42.    fulldisas:boolean=true;{long output string?                              }
  43.  
  44. var
  45.    inst : string;{should not be accessed normally}{instruction: MOV,XOR,XLAT}
  46.    pist : string;{should not be accessed normally}{segment override: ES:,DS:}
  47.    list : string;{should not be accessed normally}{prefix inst:LOCK,REP,REPZ}
  48.    o1st : string;{should not be accessed normally}{first operand            }
  49.    o2st : string;{should not be accessed normally}{second operand,(w/third) }
  50.  
  51.    procedure disasnext;
  52.    procedure disas(s,o:word);
  53.    procedure disasptr(p:pointer;c:byte);
  54.    procedure disasptrl(p:pointer;c:byte;l:byte);
  55.  
  56.    function  oldio:word;{should not be accessed normally}
  57.  
  58. {util use}
  59. type
  60.    s2 = string[2];
  61.    s3 = string[3];
  62.    s4 = string[4];
  63.    s5 = string[5];
  64.  
  65.    function hxb(x:byte):s2;
  66.    function hxw(x:word):s4;
  67.    function hxbs(x:shortint):s3;
  68.    function hxws(x:integer):s5;
  69.  
  70. implementation
  71.  
  72. type
  73.    s6 = string[6];
  74.    s7 = string[7];
  75.  
  76. const
  77.    reg08 : array[$0..$7]of s2
  78.          = ('al','cl','dl','bl','ah','ch','dh','bh');
  79.    reg16 : array[$0..$7]of s2
  80.          = ('ax','cx','dx','bx','sp','bp','si','di');
  81.    reg32 : array[$0..$7]of s3
  82.          = ('eax','ecx','edx','ebx','esp','ebp','esi','edi');
  83.    regCR : array[$0..$7]of s3
  84.          = ('cr0','CR?','cr2','cr3','CR?','CR?','CR?','CR?');
  85.    regDR : array[$0..$7]of s3
  86.          = ('dr0','dr1','dr2','dr3','DR?','DR?','dr6','dr7');
  87.    regTR : array[$0..$7]of s3
  88.          = ('TR?','TR?','TR?','TR?','TR?','TR?','tr6','tr7');
  89.    regsg : array[$0..$5]of s2
  90.          = ('es','cs','ss','ds','fs','gs');
  91.    sjmps : array[$0..$F]of s3
  92.          = ('jo','jno','jb','jnb','jz','jnz','ja','jna',
  93.             'js','jns','jp','jnp','jl','jnl','jg','jg');
  94.    loops : array[$0..$3]of s6
  95.          = ('loopne','loope','loop','jcxz');
  96.    shfts : array[$0..$7]of s3
  97.          = ('rol','ror','rcl','rcr','shl','shr','shl','sar');
  98.    addgr : array[$0..$7]of s3
  99.          = ('add','or','adc','sbb','and','sub','xor','cmp');
  100.    sets  : array[$0..$F]of s5
  101.          = ('seto','setno','setb','setnb','setz','setnz','seta','setna',
  102.             'sets','setns','setp','setnp','setl','setnl','setg','setng');
  103.    a16m1 : array[$0..$7]of s7
  104.          = ('[bx+si]','[bx+di]','[bp+si]','[bp+di]','[si]','[di]','[','[bx]');
  105.    a16m2 : array[$0..$7]of s6
  106.          = ('[bx+si','[bx+di','[bp+si','[bp+di','[si','[di','[bp','[bx');
  107.    a32m1 : array[$0..$7]of s5
  108.          = ('[eax]','[ecx]','[edx]','[ebx]','','[','[esi]','[edi]');
  109.    a32m2 : array[$0..$7]of s4
  110.          = ('[eax','[ecx','[edx','[ebx','','[ebp','[esi','[edi');
  111. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  112. { utility functions                                                         }
  113. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  114. {---------------------------------------------------------------------------}
  115. { returns 2 digit hex string of input byte                                  }
  116. {---------------------------------------------------------------------------}
  117. function hxb(x:byte):s2;assembler;
  118. asm
  119.    les  di,@result
  120.    mov  byte ptr es:[di],2
  121.    mov  dl,x
  122.    mov  al,dl
  123.    shr  al,4
  124.    add  al,90h
  125.    daa
  126.    adc  al,40h
  127.    daa
  128.    mov  byte ptr es:[di+1],al
  129.    mov  al,dl
  130.    and  al,0fh
  131.    add  al,90h
  132.    daa
  133.    adc  al,40h
  134.    daa
  135.    mov  byte ptr es:[di+2],al
  136. end;
  137. {---------------------------------------------------------------------------}
  138. { returns 4 digit hex string of input word                                  }
  139. {---------------------------------------------------------------------------}
  140. function hxw(x:word):s4;assembler;
  141. asm
  142.    les  di,@result
  143.    mov  byte ptr es:[di],4
  144.    mov  dx,x
  145.    mov  al,dh
  146.    shr  al,4
  147.    add  al,90h
  148.    daa
  149.    adc  al,40h
  150.    daa
  151.    mov  byte ptr es:[di+1],al
  152.    mov  al,dh
  153.    and  al,0fh
  154.    add  al,90h
  155.    daa
  156.    adc  al,40h
  157.    daa
  158.    mov  byte ptr es:[di+2],al
  159.    mov  al,dl
  160.    shr  al,4
  161.    add  al,90h
  162.    daa
  163.    adc  al,40h
  164.    daa
  165.    mov  byte ptr es:[di+3],al
  166.    mov  al,dl
  167.    and  al,0fh
  168.    add  al,90h
  169.    daa
  170.    adc  al,40h
  171.    daa
  172.    mov  byte ptr es:[di+4],al
  173. end;
  174. {---------------------------------------------------------------------------}
  175. { returns 3 digit signed hex string of input byte                           }
  176. {---------------------------------------------------------------------------}
  177. function hxbs(x:shortint):s3;assembler;
  178. asm
  179.    mov  ah,'+'
  180.    mov  al,x
  181.    test al,80h
  182.    jz   @pz
  183.    mov  ah,'-'
  184.    neg  al
  185. @pz:
  186.    les  di,@result
  187.    mov  byte ptr es:[di],3
  188.    mov  byte ptr es:[di+1],ah
  189.    mov  ah,al
  190.    shr  al,4
  191.    add  al,90h
  192.    daa
  193.    adc  al,40h
  194.    daa
  195.    mov  byte ptr es:[di+2],al
  196.    mov  al,ah
  197.    and  al,0fh
  198.    add  al,90h
  199.    daa
  200.    adc  al,40h
  201.    daa
  202.    mov  byte ptr es:[di+3],al
  203. end;
  204. {---------------------------------------------------------------------------}
  205. { returns 5 digit signed hex string of input word                           }
  206. {---------------------------------------------------------------------------}
  207. function hxws(x:integer):s5;assembler;
  208. asm
  209.    mov  ah,'+'
  210.    mov  dx,x
  211.    test dx,8000h
  212.    jz   @pz
  213.    mov  ah,'-'
  214.    neg  dx
  215. @pz:
  216.    les  di,@result
  217.    mov  byte ptr es:[di],5
  218.    mov  byte ptr es:[di+1],ah
  219.    mov  al,dh
  220.    shr  al,4
  221.    add  al,90h
  222.    daa
  223.    adc  al,40h
  224.    daa
  225.    mov  byte ptr es:[di+2],al
  226.    mov  al,dh
  227.    and  al,0fh
  228.    add  al,90h
  229.    daa
  230.    adc  al,40h
  231.    daa
  232.    mov  byte ptr es:[di+3],al
  233.    mov  al,dl
  234.    shr  al,4
  235.    add  al,90h
  236.    daa
  237.    adc  al,40h
  238.    daa
  239.    mov  byte ptr es:[di+4],al
  240.    mov  al,dl
  241.    and  al,0fh
  242.    add  al,90h
  243.    daa
  244.    adc  al,40h
  245.    daa
  246.    mov  byte ptr es:[di+5],al
  247. end;
  248. {---------------------------------------------------------------------------}
  249. { returns low nib                                                           }
  250. {---------------------------------------------------------------------------}
  251. function lnib(x:byte):byte;assembler;
  252. asm
  253.    mov al,x
  254.    and al,0fh
  255. end;
  256. {---------------------------------------------------------------------------}
  257. { returns high nib                                                          }
  258. {---------------------------------------------------------------------------}
  259. function hnib(x:byte):byte;assembler;
  260. asm
  261.    mov al,x
  262.    shr al,4
  263. end;
  264. {---------------------------------------------------------------------------}
  265. { returns mod / ss field                                                    }
  266. {---------------------------------------------------------------------------}
  267. function mo(x:byte):byte;assembler;
  268. asm
  269.    mov al,x
  270.    shr al,6
  271. end;
  272. {---------------------------------------------------------------------------}
  273. { returns r/m / base field                                                  }
  274. {---------------------------------------------------------------------------}
  275. function rm(x:byte):byte;assembler;
  276. asm
  277.    mov al,x
  278.    and al,07h
  279. end;
  280. {---------------------------------------------------------------------------}
  281. { returns reg / index field                                                 }
  282. {---------------------------------------------------------------------------}
  283. function rg(x:byte):byte;assembler;
  284. asm
  285.    mov al,x
  286.    and al,38h
  287.    shr al,3
  288. end;
  289. {---------------------------------------------------------------------------}
  290. { instruction variables                                                     }
  291. var
  292.     cd   : byte;    { current decoding, offset to instruction start         }
  293.     wf   : byte;    { width field of the instruction 0=8,1=16,else none=1   }
  294.     ad   : byte;    { displacement size in bytes                            }
  295.     id   : byte;    { immediate data size in bytes                          }
  296.     ea32 : boolean; { effective address size prefix found, default 16       }
  297.     os32 : boolean; { operand size prefix found, default 16 assumed         }
  298. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  299. { field decoders                                                            }
  300. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  301. {---------------------------------------------------------------------------}
  302. { returns general register from regs field of mod reg r/m byte at is:io     }
  303. {---------------------------------------------------------------------------}
  304. procedure regs(var s:string);
  305. begin
  306.   if(wf=0) then s:=reg08[rg(mem[is:io+cd])]
  307.            else begin
  308.                 if(os32) then s:=reg32[rg(mem[is:io+cd])]
  309.                          else s:=reg16[rg(mem[is:io+cd])];
  310.                 end;
  311. end;
  312. {---------------------------------------------------------------------------}
  313. { returns control register from regs field of mod reg r/m byte at is:io     }
  314. {---------------------------------------------------------------------------}
  315. procedure cregs(var s:string);
  316. begin
  317.    s:=regCR[rg(mem[is:io+cd])];
  318. end;
  319. {---------------------------------------------------------------------------}
  320. { returns debug register from regs field of mod reg r/m byte at is:io       }
  321. {---------------------------------------------------------------------------}
  322. procedure dregs(var s:string);
  323. begin
  324.    s:=regDR[rg(mem[is:io+cd])];
  325. end;
  326. {---------------------------------------------------------------------------}
  327. { returns test register from regs field of mod reg r/m byte at is:io        }
  328. {---------------------------------------------------------------------------}
  329. procedure tregs(var s:string);
  330. begin
  331.    s:=regTR[rg(mem[is:io+cd])];
  332. end;
  333. {---------------------------------------------------------------------------}
  334. { returns argument from mod r/m fields of mod regs r/m byte at is:io        }
  335. {---------------------------------------------------------------------------}
  336. procedure modrm(var s:string);
  337. var
  338.     x   : byte;
  339.     tst : string;
  340.   {---------------------------------------------------}
  341.   { returns register from r/m field                   }
  342.   {---------------------------------------------------}
  343.   procedure SelectReg;
  344.   begin
  345.   if(wf=0) then s:=reg08[rm(x)]
  346.            else begin
  347.                 if(os32) then s:=reg32[rm(x)]
  348.                          else s:=reg16[rm(x)];
  349.                 end;
  350.   end;
  351.   {---------------------------------------------------}
  352.   { returns scaled index in tst when sib is at is:io  }
  353.   {---------------------------------------------------}
  354.   procedure scale;
  355.   begin
  356.     tst:='';
  357.     case rg(mem[is:io+cd]) of {index}
  358.       0: tst:='+(eax';
  359.       1: tst:='+(ecx';
  360.       2: tst:='+(edx';
  361.       3: tst:='+(ebx';
  362.       4: begin
  363.          tst:='';
  364.          if mo(mem[is:io+cd])<>0 then tst:='???';
  365.          exit;
  366.          end;
  367.       5: tst:='+(ebp';
  368.       6: tst:='+(esi';
  369.       7: tst:='+(edi';
  370.     end;{case}
  371.  
  372.     case mo(mem[is:io+cd]) of {scale}
  373.       0: tst:=tst+')';
  374.       1: tst:=tst+'*2)';
  375.       2: tst:=tst+'*4)';
  376.       3: tst:=tst+'*8)';
  377.     end;{case}
  378.   end;
  379.   {---------------------------------------------------}
  380. begin
  381.  
  382. x:=mem[is:io+cd];
  383.  
  384. if not(ea32) then begin
  385.  
  386. case mo(x) of
  387.  $0:begin
  388.     s:=a16m1[rm(x)];
  389.     if(rm(x)=6)then begin
  390.                     s:=s+hxw(memw[is:io+cd+1])+']';
  391.                     ad:=2;
  392.                     end;
  393.     end;
  394.  $1:begin
  395.     s:=a16m2[rm(x)]+hxbs(shortint(mem[is:io+cd+1]))+']';
  396.     ad:=1;
  397.     end;
  398.  $2:begin
  399.     s:=a16m2[rm(x)]+hxws(integer(memw[is:io+cd+1]))+']';
  400.     ad:=2;
  401.     end;
  402.  $3:SelectReg;
  403.  
  404. end;{mo case}
  405.  
  406. end else begin {32 bit addressing mode}
  407.  
  408. case mo(x) of
  409. $0:begin
  410.    case rm(x) of
  411.    0..3,
  412.    5..7:begin
  413.         s:=a32m1[rm(x)];
  414.         if(rm(x)=5)
  415.           then begin
  416.                s:=s+hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1])+']';
  417.                ad:=4;
  418.                end;
  419.         end;
  420.       4:begin
  421.         inc(cd);
  422.         scale;
  423.         if(rm(mem[is:io+cd])<>5)
  424.           then begin
  425.                s:='['+reg32[rm(mem[is:io+cd])]+tst+']';
  426.                end
  427.           else begin
  428.                s:='['+hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1])+tst+']';
  429.                ad:=4;
  430.                end;
  431.         dec(cd);
  432.         inc(id);
  433.         end;
  434.    end;{case}
  435.    end;
  436. $1:begin
  437.    if(rm(x)<>4)
  438.      then begin
  439.           s:=a32m2[rm(x)]+hxbs(shortint(mem[is:io+cd+1]))+']';
  440.           ad:=1;
  441.           end
  442.      else begin
  443.           inc(cd);
  444.           scale;
  445.           s:='['+reg32[rm(mem[is:io+cd])]+tst
  446.              +hxbs(shortint(mem[is:io+cd+1]))+']';
  447.           ad:=1;
  448.           dec(cd);
  449.           inc(id);
  450.           end;
  451.    end;
  452. $2:begin
  453.    if(rm(x)<>4)
  454.      then begin
  455.           s:=a32m2[rm(x)]+'+'+hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1])+']';
  456.           ad:=4;
  457.           end
  458.      else begin
  459.           inc(cd);scale;
  460.           s:='['+reg32[rm(mem[is:io+cd])]+tst+'+'
  461.              +hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1])+']';
  462.           ad:=4;
  463.           dec(cd);
  464.           inc(id);
  465.           end;
  466.    end;
  467. $3:SelectReg;
  468.    end;{mo case}
  469. end;{32?16}
  470.  
  471.   s:=pist+s;
  472.   pist:='';
  473.  
  474. end;
  475. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  476. {    Instruction Crackers                                                   }
  477. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  478. procedure EbGb(const s:string);
  479. begin
  480.    inst:=s;
  481.    inc(cd);
  482.    wf:=0;
  483.    modrm(o1st);
  484.    regs(o2st);
  485. end;
  486. {--------------------------------------------------------------------------}
  487. procedure EvGv(const s:string);
  488. begin
  489.    inst:=s;
  490.    inc(cd);
  491.    modrm(o1st);
  492.    regs(o2st);
  493. end;
  494. {--------------------------------------------------------------------------}
  495. procedure GbEb(const s:string);
  496. begin
  497.    inst:=s;
  498.    inc(cd);
  499.    wf:=0;
  500.    modrm(o2st);
  501.    regs(o1st);
  502. end;
  503. {--------------------------------------------------------------------------}
  504. procedure GvEv(const s:string);
  505. begin
  506.    inst:=s;
  507.    inc(cd);
  508.    modrm(o2st);
  509.    regs(o1st);
  510. end;
  511. {--------------------------------------------------------------------------}
  512. procedure ALIb(const s:string);
  513. begin
  514.    inst:=s;
  515.    o1st:='al';
  516.    id:=1;
  517.    o2st:=hxb(mem[is:io+cd+1]);
  518. end;
  519. {--------------------------------------------------------------------------}
  520. procedure eAXIv(const s:string);
  521. begin
  522.    inst:=s;
  523.    if(not(os32))
  524.      then begin
  525.           id:=2;
  526.           o1st:='ax';
  527.           o2st:=hxw(memw[is:io+cd+1]);
  528.           end
  529.      else begin
  530.           id:=4;
  531.           o1st:='eax';
  532.           o2st:=hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1]);
  533.           end;
  534. end;
  535. {--------------------------------------------------------------------------}
  536. procedure eAXIb(const s:string);
  537. begin
  538.    inst:=s;
  539.    id:=1;
  540.    o2st:=hxb(mem[is:io+cd+1]);
  541.    if not(os32) then o1st:='ax'
  542.                 else o1st:='eax';
  543. end;
  544. {--------------------------------------------------------------------------}
  545. procedure Ap(const s:string);
  546. begin
  547.    inst:=s;
  548.    if(not(os32))
  549.      then begin
  550.           id:=4;
  551.           o1st:=hxw(memw[is:io+cd+3])+':'+hxw(memw[is:io+cd+1]);
  552.           end
  553.      else begin
  554.           id:=6;
  555.           o1st:=hxw(memw[is:io+cd+5])+':'
  556.                 +hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1]);
  557.           end;
  558. end;
  559. {--------------------------------------------------------------------------}
  560. procedure Jb(const s:string);
  561. begin
  562.    inst:=s;
  563.    id:=1;
  564.    o1st:=hxw(io+2+shortint(mem[is:io+cd+1]));
  565. end;
  566. {--------------------------------------------------------------------------}
  567. procedure Jv(const s:string);
  568. begin
  569.    inst:=s;
  570.    if(not(os32))
  571.      then begin
  572.           id:=2;
  573.           o1st:=hxw(io+3+integer(memw[is:io+cd+1]));
  574.           end
  575.      else begin
  576.           id:=4;
  577.           o1st:='EIP+'+hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1]);
  578.           end;
  579. end;
  580. {--------------------------------------------------------------------------}
  581. procedure Jv2(const s:string);
  582. begin
  583.    inst:=s;
  584.    if(not(os32))
  585.      then begin
  586.           id:=2;
  587.           o1st:=hxw(io+4+integer(memw[is:io+cd+1]));
  588.           end
  589.      else begin
  590.           id:=4;
  591.           o1st:='EIP+'+hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1]);
  592.           end;
  593. end;
  594. {--------------------------------------------------------------------------}
  595. procedure simple1(const s:string);
  596. begin
  597.    inst:=s;
  598. end;
  599. {--------------------------------------------------------------------------}
  600. procedure simple2(const s,p1:string);
  601. begin
  602.    inst:=s;
  603.    o1st:=p1;
  604. end;
  605. {--------------------------------------------------------------------------}
  606. procedure simple3(const s,p1,p2:string);
  607. begin
  608.    inst:=s;
  609.    o1st:=p1;
  610.    o2st:=p2;
  611. end;
  612. {--------------------------------------------------------------------------}
  613. procedure swapp;
  614. var
  615.    t:string;
  616. begin
  617.    t:=o1st;
  618.    o1st:=o2st;
  619.    o2st:=t;
  620. end;
  621. {--------------------------------------------------------------------------}
  622. procedure segop(const s:string);
  623. begin
  624.    pist:=pist+s;
  625.    inc(cd);
  626. end;
  627. {--------------------------------------------------------------------------}
  628. procedure legop(const s:string);
  629. begin
  630.    list:=s;
  631.    inc(cd);
  632. end;
  633. {--------------------------------------------------------------------------}
  634. procedure genreg1;
  635. begin
  636.    if not(os32) then o1st:=reg16[lnib(mem[is:io+cd]) mod 8]
  637.                 else o1st:=reg32[lnib(mem[is:io+cd]) mod 8];
  638. end;
  639. {--------------------------------------------------------------------------}
  640. procedure genreg2;
  641. begin
  642.    if not(os32) then o2st:=reg16[lnib(mem[is:io+cd]) mod 8]
  643.                 else o2st:=reg32[lnib(mem[is:io+cd]) mod 8];
  644. end;
  645. {--------------------------------------------------------------------------}
  646. procedure eAX1;
  647. begin
  648.    if not(os32) then o1st:='ax'
  649.                 else o1st:='eax';
  650. end;
  651. {--------------------------------------------------------------------------}
  652. procedure eAX2;
  653. begin
  654.    if not(os32) then o2st:='ax'
  655.                 else o2st:='eax';
  656. end;
  657. {--------------------------------------------------------------------------}
  658. procedure width1(const s,w:string);
  659. begin
  660.    if os32 then inst:=w
  661.            else inst:=s;
  662. end;
  663. {--------------------------------------------------------------------------}
  664. procedure byteo1;
  665. begin
  666.    if o1st[length(o1st)]=']' then o1st:='byte ptr '+o1st;
  667. end;
  668. {--------------------------------------------------------------------------}
  669. procedure wordo1;
  670. begin
  671.    if(o1st[length(o1st)]=']')
  672.      then if os32 then o1st:='dword ptr '+o1st
  673.                   else o1st:='word ptr '+o1st;
  674. end;
  675. {--------------------------------------------------------------------------}
  676. procedure dwordo1;
  677. begin
  678.    if(o1st[length(o1st)]=']')
  679.      then if os32 then o1st:='16:32 ptr '+o1st
  680.                   else o1st:='dword ptr '+o1st;
  681. end;
  682. {--------------------------------------------------------------------------}
  683. procedure dwordo2;
  684. begin
  685.    if(o2st[length(o2st)]=']')
  686.      then if os32 then o2st:='16:32 ptr '+o2st
  687.                   else o2st:='dword ptr '+o2st;
  688. end;
  689. {--------------------------------------------------------------------------}
  690. procedure memchk2;
  691. begin
  692.    if(o2st[length(o2st)]<>']')
  693.      then begin
  694.           inst:='';
  695.           o1st:='';
  696.           o2st:='';
  697.           dec(cd);
  698.           end;{ad is not important, if it is mem it is ok}
  699. end;
  700. {--------------------------------------------------------------------------}
  701. procedure memchk2r;
  702. begin
  703.    if(o1st[length(o2st)]=']')
  704.      then begin
  705.           inst:='';
  706.           o1st:='';
  707.           o2st:='';
  708.           dec(cd,ad);
  709.           ad:=0;
  710.           end;{ad is important! }
  711. end;
  712. {--------------------------------------------------------------------------}
  713. procedure Ebi(const s:string);
  714. begin
  715.    inst:=s;
  716.    wf:=0;
  717.    modrm(o1st);
  718.    byteo1;
  719. end;
  720. {--------------------------------------------------------------------------}
  721. procedure Evi(const s:string);
  722. begin
  723.    inst:=s;
  724.    modrm(o1st);
  725.    wordo1;
  726. end;
  727. {--------------------------------------------------------------------------}
  728. procedure EbIbi(const s:string);
  729. begin
  730.    inst:=s;
  731.    id:=1;
  732.    wf:=0;
  733.    modrm(o1st);
  734.    byteo1;
  735.    o2st:=hxb(mem[is:io+cd+ad+1]);
  736. end;
  737. {--------------------------------------------------------------------------}
  738. procedure EvIvi(const s:string);
  739. begin
  740.    inst:=s;
  741.    modrm(o1st);
  742.    if(not(os32))
  743.      then begin
  744.           id:=2;
  745.           o2st:=hxw(memw[is:io+cd+ad+1]);
  746.           if o1st[length(o1st)]=']' then o1st:='word ptr '+o1st;
  747.           end
  748.      else begin
  749.           id:=4;
  750.           if o1st[length(o1st)]=']' then o1st:='dword ptr '+o1st;
  751.           o2st:=hxw(memw[is:io+cd+ad+3])+
  752.           hxw(memw[is:io+cd+ad+1]);
  753.           end;
  754. end;
  755. {--------------------------------------------------------------------------}
  756. procedure EvIbi(const s:string);
  757. begin
  758.    inst:=s;
  759.    modrm(o1st);
  760.    id:=1;
  761.    wordo1;
  762.    o2st:=hxb(mem[is:io+cd+ad+1]);
  763. end;
  764. {--------------------------------------------------------------------------}
  765. procedure eP(const s:string);
  766. begin
  767.    inst:=s;
  768.    modrm(o1st);
  769.    dwordo1;
  770. end;
  771. {--------------------------------------------------------------------------}
  772. procedure movALOb;
  773. begin
  774.   inst:='mov';
  775.   o1st:='al';
  776.   if(ea32)
  777.     then begin
  778.          id:=4;
  779.          o2st:='['+hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1])+']';
  780.          end
  781.     else begin
  782.          id:=2;
  783.          o2st:='['+hxw(memw[is:io+cd+1])+']';
  784.          end;
  785.   if(pist<>'')
  786.     then begin
  787.          o2st:=pist+o2st;
  788.          pist:='';
  789.          end;
  790. end;
  791. {--------------------------------------------------------------------------}
  792. procedure moveAXOv;
  793. begin
  794.   inst:='mov';
  795.   if os32 then o1st:='eax'
  796.           else o1st:='ax';
  797.   if(ea32)
  798.     then begin
  799.          id:=4;
  800.          o2st:='['+hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1])+']';
  801.          end
  802.     else begin
  803.          id:=2;
  804.          o2st:='['+hxw(memw[is:io+cd+1])+']';
  805.          end;
  806.   if(pist<>'')
  807.     then begin
  808.          o2st:=pist+o2st;
  809.          pist:='';
  810.          end;
  811. end;
  812. {--------------------------------------------------------------------------}
  813. procedure Iv(const s:string);
  814. begin
  815.    inst:=s;
  816.    if(os32)
  817.      then begin
  818.           id:=4;
  819.           o1st:=hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1]);
  820.           end
  821.      else begin
  822.           id:=2;
  823.           o1st:=hxw(memw[is:io+cd+1]);
  824.           end;
  825. end;
  826. {--------------------------------------------------------------------------}
  827. procedure Ib(const s:string);
  828. begin
  829.    inst:=s;
  830.    id:=1;
  831.    o1st:=hxb(mem[is:io+cd+1]);
  832. end;
  833. {--------------------------------------------------------------------------}
  834. procedure Ewi(const s:string);
  835. begin
  836.    inst:=s;
  837.    modrm(o1st);
  838.    if o1st[length(o1st)]=']' then o1st:='word ptr '+o1st;
  839. end;
  840. {--------------------------------------------------------------------------}
  841. procedure Ms(const s:string);
  842. begin
  843.    inst:=s;
  844.    modrm(o1st);
  845.    if(o1st[length(o1st)]<>']')
  846.      then begin
  847.           inst:='';
  848.           o1st:='';
  849.           o2st:='';
  850.           dec(cd);
  851.           end;{ad is not important, if it is mem it is ok}
  852. end;
  853. {--------------------------------------------------------------------------}
  854. procedure CdRd(const s:string);
  855. begin
  856.    os32:=true;
  857.    inst:=s;
  858.    inc(cd);
  859.    cregs(o1st);
  860.    modrm(o2st);
  861.    if o2st[length(o2st)]=']' then o2st:=o2st+'?';
  862. end;
  863. {--------------------------------------------------------------------------}
  864. procedure DdRd(const s:string);
  865. begin
  866.    os32:=true;
  867.    inst:=s;
  868.    inc(cd);
  869.    dregs(o1st);
  870.    modrm(o2st);
  871.    if o2st[length(o2st)]=']' then o2st:=o2st+'?';
  872. end;
  873. {--------------------------------------------------------------------------}
  874. procedure TdRd(const s:string);
  875. begin
  876.    os32:=true;
  877.    inst:=s;
  878.    inc(cd);
  879.    tregs(o1st);
  880.    modrm(o2st);
  881.    if o2st[length(o2st)]=']' then o2st:=o2st+'?';
  882. end;
  883. {--------------------------------------------------------------------------}
  884. procedure GvEb(const s:string);
  885. begin
  886.    inst:=s;
  887.    inc(cd);
  888.    regs(o1st);
  889.    os32:=false;
  890.    modrm(o2st);
  891.    if o2st[length(o2st)]=']' then o2st:='byte ptr '+o2st;
  892. end;
  893. {--------------------------------------------------------------------------}
  894. procedure GvEw(const s:string);
  895. begin
  896.    inst:=s;
  897.    inc(cd);
  898.    regs(o1st);
  899.    os32:=false;
  900.    modrm(o2st);
  901.    if o2st[length(o2st)]=']' then o2st:='word ptr '+o2st;
  902. end;
  903. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  904. {                 two byte inst decode                                      }
  905. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  906. procedure twobyte;
  907. begin
  908.    inc(cd);
  909.    case hnib(mem[is:io+cd]) of
  910.    $0:begin
  911.       case lnib(mem[is:io+cd]) of
  912.        $0:begin
  913.           inc(cd);
  914.           case rg(mem[is:io+cd]) of
  915.            0:Ewi('sldt');
  916.            1:Ewi('str');
  917.            2:Ewi('lldt');
  918.            3:Ewi('ltr');
  919.            4:Ewi('verr');
  920.            5:Ewi('verw');
  921.            6:dec(cd);
  922.            7:dec(cd);
  923.              end;
  924.           end;
  925.        $1:begin
  926.           inc(cd);
  927.           case rg(mem[is:io+cd]) of
  928.            0:Ms('sgdt');
  929.            1:Ms('sidt');
  930.            2:Ms('lgdt');
  931.            3:Ms('lidt');
  932.            4:Ewi('smsw');
  933.            5:dec(cd);
  934.            6:Ewi('lmsw');
  935.            7:dec(cd);
  936.              end;
  937.           end;
  938.        $2:GvEv('lar');
  939.        $3:GvEv('lsl');
  940.        $5:simple1('loadall');
  941.        $6:simple1('clts');
  942.           end;
  943.       end;
  944.    $2:begin
  945.       case lnib(mem[is:io+cd]) of
  946.        $0:CdRd('mov');
  947.        $1:DdRd('mov');
  948.        $2:begin
  949.           CdRd('mov');
  950.           swapp;
  951.           end;
  952.        $3:begin
  953.           DdRd('mov');
  954.           swapp;
  955.           end;
  956.        $4:TdRd('mov');
  957.        $6:begin
  958.           TdRd('mov');
  959.           swapp;
  960.           end;
  961.           end;{case}
  962.       end;
  963.    $8:Jv2(sjmps[lnib(mem[is:io+cd])]);
  964.    $9:begin
  965.       inc(cd);
  966.       Ebi(sets[lnib(mem[is:io+cd-1])]);
  967.       end;
  968.    $A:begin
  969.       case lnib(mem[is:io+cd]) of
  970.       $0:simple2('push','fs');
  971.       $1:simple2('pop','fs');
  972.       $3:EvGv('bt');
  973.       $4:begin
  974.          inst:='shld';
  975.          inc(cd);
  976.          modrm(o1st);
  977.          regs(o2st);
  978.          id:=1;
  979.          o2st:=o2st+','+hxb(mem[is:io+cd+ad+1]);
  980.          end;
  981.       $5:begin
  982.          inst:='shld';
  983.          inc(cd);
  984.          modrm(o1st);
  985.          regs(o2st);
  986.          o2st:=o2st+',cl';
  987.          end;
  988.       $8:simple2('push','gs');
  989.       $9:simple2('pop','gs');
  990.       $B:EvGv('bts');
  991.       $C:begin
  992.          inst:='shrd';
  993.          inc(cd);
  994.          modrm(o1st);
  995.          regs(o2st);
  996.          id:=1;
  997.          o2st:=o2st+','+hxb(mem[is:io+cd+ad+1]);end;
  998.       $D:begin
  999.          inst:='shrd';
  1000.          inc(cd);
  1001.          modrm(o1st);
  1002.          regs(o2st);
  1003.          o2st:=o2st+',cl';
  1004.          end;
  1005.       $F:GvEv('imul');
  1006.          end;{case}
  1007.       end;
  1008.    $B:begin
  1009.       case lnib(mem[is:io+cd]) of
  1010.       $2:begin
  1011.          inst:='lss';
  1012.          inc(cd);
  1013.          modrm(o2st);
  1014.          regs(o1st);
  1015.          dwordo2;
  1016.          memchk2;
  1017.          end;
  1018.       $3:EvGv('btr');
  1019.       $4:begin
  1020.          inst:='lfs';
  1021.          inc(cd);
  1022.          modrm(o2st);
  1023.          regs(o1st);
  1024.          dwordo2;memchk2;
  1025.          end;
  1026.       $5:begin
  1027.          inst:='lgs';
  1028.          inc(cd);
  1029.          modrm(o2st);
  1030.          regs(o1st);
  1031.          dwordo2;memchk2;
  1032.          end;
  1033.       $6:GvEb('movzx');
  1034.       $7:GvEw('movzx');
  1035.       $A:begin
  1036.          inc(cd);
  1037.          case rg(mem[is:io+cd]) of
  1038.            0..3:dec(cd);
  1039.            4:EvIbi('bt');
  1040.            5:EvIbi('bts');
  1041.            6:EvIbi('btr');
  1042.            7:EvIbi('btc');
  1043.              end;{case}
  1044.           end;
  1045.       $B:EvGv('btc');
  1046.       $C:GvEv('bsf');
  1047.       $D:GvEv('bsr');
  1048.       $E:GvEb('movsx');
  1049.       $F:GvEw('movsx');
  1050.          end;{case}
  1051.       end;
  1052.       end;
  1053.  
  1054.    if(inst='') then dec(cd);
  1055.  
  1056. end;
  1057. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  1058. {                 One byte inst decode                                      }
  1059. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  1060. procedure onebyte;
  1061. label
  1062.    again;
  1063. var
  1064.    cm:byte;
  1065. begin
  1066.    cd   := 0;
  1067.    wf   := 1; {none}
  1068.    ad   := 0;
  1069.    id   := 0;
  1070.    ea32 := false; {should be checked for default!}
  1071.    os32 := false;
  1072.    inst := '';
  1073.    pist := '';
  1074.    list := '';
  1075.    o1st := '';
  1076.    o2st := '';
  1077.  
  1078. again:
  1079.  
  1080.    cm := mem[is:io+cd];
  1081.  
  1082.    case hnib(cm) of
  1083. {///////////////////////////////////////////////////////////////////////////}
  1084.   $0:begin
  1085.      case lnib(cm) of
  1086.      $0:EbGb('add');
  1087.      $1:EvGv('add');
  1088.      $2:GbEb('add');
  1089.      $3:GvEv('add');
  1090.      $4:ALIb('add');
  1091.      $5:eAXIv('add');
  1092.      $6:simple2('push','es');
  1093.      $7:simple2('pop','es');
  1094.      $8:EbGb('or');
  1095.      $9:EvGv('or');
  1096.      $A:GbEb('or');
  1097.      $B:GvEv('or');
  1098.      $C:ALIb('or');
  1099.      $D:eAXIv('or');
  1100.      $E:simple2('push','cs');
  1101.      $F:twobyte;
  1102.         end;
  1103.      end;{0}
  1104. {///////////////////////////////////////////////////////////////////////////}
  1105.   $1:begin
  1106.      case lnib(cm) of
  1107.      $0:EbGb('adc');
  1108.      $1:EvGv('adc');
  1109.      $2:GbEb('adc');
  1110.      $3:GvEv('adc');
  1111.      $4:ALIb('adc');
  1112.      $5:eAXIv('adc');
  1113.      $6:simple2('push','ss');
  1114.      $7:simple2('pop','ss');
  1115.      $8:EbGb('sbb');
  1116.      $9:EvGv('sbb');
  1117.      $A:GbEb('sbb');
  1118.      $B:GvEv('sbb');
  1119.      $C:ALIb('sbb');
  1120.      $D:eAXIv('sbb');
  1121.      $E:simple2('push','ds');
  1122.      $F:simple2('pop','ds');
  1123.         end;
  1124.      end;{1}
  1125. {///////////////////////////////////////////////////////////////////////////}
  1126.   $2:begin
  1127.      case lnib(cm) of
  1128.      $0:EbGb('and');
  1129.      $1:EvGv('and');
  1130.      $2:GbEb('and');
  1131.      $3:GvEv('and');
  1132.      $4:ALIb('and');
  1133.      $5:eAXIv('and');
  1134.      $6:begin
  1135.         segop('es:');
  1136.         goto again;
  1137.         end;
  1138.      $7:simple1('daa');
  1139.      $8:EbGb('sub');
  1140.      $9:EvGv('sub');
  1141.      $A:GbEb('sub');
  1142.      $B:GvEv('sub');
  1143.      $C:ALIb('sub');
  1144.      $D:eAXIv('sub');
  1145.      $E:begin
  1146.         segop('cs:');
  1147.         goto again;
  1148.         end;
  1149.      $F:simple1('das');
  1150.         end;
  1151.      end;{2}
  1152. {///////////////////////////////////////////////////////////////////////////}
  1153.   $3:begin
  1154.      case lnib(cm) of
  1155.      $0:EbGb('xor');
  1156.      $1:EvGv('xor');
  1157.      $2:GbEb('xor');
  1158.      $3:GvEv('xor');
  1159.      $4:ALIb('xor');
  1160.      $5:eAXIv('xor');
  1161.      $6:begin
  1162.         segop('ss:');
  1163.         goto again;
  1164.         end;
  1165.      $7:simple1('aaa');
  1166.      $8:EbGb('cmp');
  1167.      $9:EvGv('cmp');
  1168.      $A:GbEb('cmp');
  1169.      $B:GvEv('cmp');
  1170.      $C:ALIb('cmp');
  1171.      $D:eAXIv('cmp');
  1172.      $E:begin
  1173.         segop('ds:');
  1174.         goto again;
  1175.         end;
  1176.      $F:simple1('aas');
  1177.         end;
  1178.      end;{3}
  1179. {///////////////////////////////////////////////////////////////////////////}
  1180.   $4:begin
  1181.      case lnib(cm) of
  1182.      $0..$7:simple1('inc');
  1183.      $7..$F:simple1('dec');
  1184.             end;
  1185.      genreg1;
  1186.      end;{4}
  1187. {///////////////////////////////////////////////////////////////////////////}
  1188.   $5:begin
  1189.      case lnib(cm) of
  1190.        $0..$7:simple1('push');
  1191.        $7..$F:simple1('pop');
  1192.               end;
  1193.      genreg1;
  1194.      end;{5}
  1195. {///////////////////////////////////////////////////////////////////////////}
  1196.   $6:begin
  1197.      case lnib(cm) of
  1198.      $0:width1('pusha','pushad');
  1199.      $1:width1('popa','popad');
  1200.      $2:begin
  1201.         inst:='bound';
  1202.         inc(cd);
  1203.         wf:=1;
  1204.         regs(o1st);
  1205.         modrm(o2st);
  1206.         memchk2;
  1207.         end;
  1208.      $3:begin
  1209.         inst:='arpl';
  1210.         inc(cd);
  1211.         wf:=1;
  1212.         regs(o2st);
  1213.         modrm(o1st);
  1214.         memchk2r;
  1215.         end;
  1216.      $4:begin
  1217.         segop('fs:');
  1218.         goto again;
  1219.         end;
  1220.      $5:begin
  1221.         segop('gs:');
  1222.         goto again;
  1223.         end;
  1224.      $6:begin
  1225.         os32:=not(os32);
  1226.         inc(cd);
  1227.         goto again;
  1228.         end;
  1229.      $7:begin
  1230.         ea32:=not(ea32);
  1231.         inc(cd);
  1232.         goto again;
  1233.         end;
  1234.      $8:Iv('push');
  1235.      $9:begin
  1236.         inst:='imul';
  1237.         wf:=1;
  1238.         inc(cd);
  1239.         regs(o1st);
  1240.         modrm(o2st);
  1241.         if os32
  1242.           then begin
  1243.                id:=4;
  1244.                o2st:=o2st+','
  1245.                      +hxw(memw[is:io+ad+cd+3])+hxw(memw[is:io+ad+cd+1]);
  1246.                end
  1247.           else begin
  1248.                id:=2;
  1249.                o2st:=o2st+','+hxw(memw[is:io+ad+cd+1]);
  1250.                end;
  1251.         end;
  1252.      $A:Ib('push');
  1253.      $B:begin
  1254.         inst:='imul';
  1255.         wf:=1;
  1256.         inc(cd);
  1257.         regs(o1st);
  1258.         modrm(o2st);
  1259.         id:=1;
  1260.         o2st:=o2st+','+hxb(mem[is:io+cd+ad+1]);
  1261.         end;
  1262.      $C:simple1('insb');
  1263.      $D:width1('insw','insd');
  1264.      $E:simple1('outsb');
  1265.      $F:width1('outsw','outsd');
  1266.         end;{case}
  1267.      end;{6}
  1268. {///////////////////////////////////////////////////////////////////////////}
  1269.   $7: Jb(sjmps[lnib(cm)]);
  1270. {///////////////////////////////////////////////////////////////////////////}
  1271.   $8:begin
  1272.      case lnib(cm) of
  1273.      $0:begin
  1274.         inc(cd);
  1275.         EbIbi(addgr[rg(mem[is:io+cd])]);
  1276.         end;
  1277.      $1:begin
  1278.         inc(cd);
  1279.         EvIvi(addgr[rg(mem[is:io+cd])]);
  1280.         end;
  1281.      $2:begin
  1282.         wf:=0;
  1283.         inc(cd);
  1284.         modrm(o1st);
  1285.         id:=1;{weird opcode!}
  1286.         inst:=addgr[rg(mem[is:io+cd])];
  1287.         byteo1;
  1288.         o2st:=hxw(shortint(mem[is:io+cd+ad+1]));
  1289.         end;
  1290.      $3:begin
  1291.         inc(cd);
  1292.         EvIbi(addgr[rg(mem[is:io+cd])]);
  1293.         end;
  1294.      $4:EbGb('test');
  1295.      $5:EvGv('test');
  1296.      $6:EbGb('xchg');
  1297.      $7:EvGv('xchg');
  1298.      $8:EbGb('mov');
  1299.      $9:EvGv('mov');
  1300.      $A:GbEb('mov');
  1301.      $B:GvEv('mov');
  1302.      $C:begin
  1303.         inst:='mov';
  1304.         inc(cd);
  1305.         modrm(o1st);
  1306.         o2st:=regsg[rg(mem[is:io+cd])];
  1307.         end;
  1308.      $D:begin
  1309.         GvEv('lea');
  1310.         memchk2;
  1311.         end;
  1312.      $E:begin
  1313.         inst:='mov';
  1314.         inc(cd);
  1315.         modrm(o2st);
  1316.         o1st:=regsg[rg(mem[is:io+cd])];
  1317.         end;
  1318.      $F:begin
  1319.         inc(cd);
  1320.         Evi('pop');
  1321.         end;
  1322.         end;{case}
  1323.      end;{8}
  1324. {///////////////////////////////////////////////////////////////////////////}
  1325.   $9:begin
  1326.      case lnib(cm) of
  1327.      $0:simple1('nop');
  1328.      $1..$7:begin
  1329.             simple1('xchg');
  1330.             eAX1;
  1331.             genreg2;
  1332.             end;
  1333.      $8:width1('cbw','cwde');
  1334.      $9:width1('cwd','cdq');
  1335.      $A:Ap('call');
  1336.      $B:simple1('wait');
  1337.      $C:width1('pushf','pushfd');
  1338.      $D:width1('popf','popfd');
  1339.      $E:simple1('sahf');
  1340.      $F:simple1('lahf');
  1341.         end;{case}
  1342.      end;{9}
  1343. {///////////////////////////////////////////////////////////////////////////}
  1344.   $A:begin
  1345.      case lnib(cm) of
  1346.      $0:movALOb;
  1347.      $1:moveAXOv;
  1348.      $2:begin
  1349.         movALOb;
  1350.         swapp;
  1351.         end;
  1352.      $3:begin
  1353.         moveAXOv;
  1354.         swapp;
  1355.         end;
  1356.      $4:simple1('movsb');
  1357.      $5:width1('movsw','movsd');
  1358.      $6:simple1('cmpsb');
  1359.      $7:width1('cmpsw','cmpsd');
  1360.      $8:ALIb('test');
  1361.      $9:eAXIv('test');
  1362.      $A:simple1('stosb');
  1363.      $B:width1('stosw','stosd');
  1364.      $C:simple1('lodsb');
  1365.      $D:width1('lodsw','lodsd');
  1366.      $E:simple1('scasb');
  1367.      $F:width1('scasw','scasd');
  1368.         end;{case}
  1369.      end;{A}
  1370. {///////////////////////////////////////////////////////////////////////////}
  1371.   $B:begin
  1372.      case lnib(cm) of
  1373.      $0..$7:begin
  1374.             inst:='mov';id:=1;
  1375.             o1st:=reg08[lnib(mem[is:io+cd])];
  1376.             o2st:=hxb(mem[is:io+cd+1]);
  1377.             end;
  1378.      $8..$F:begin
  1379.             inst:='mov';
  1380.             if os32
  1381.               then begin
  1382.                    id:=4;
  1383.                    o1st:=reg32[lnib(mem[is:io+cd])mod 8];
  1384.                    o2st:=hxw(memw[is:io+cd+3])+hxw(memw[is:io+cd+1]);
  1385.                    end
  1386.               else begin
  1387.                    id:=2;
  1388.                    o1st:=reg16[lnib(mem[is:io+cd])mod 8];
  1389.                    o2st:=hxw(memw[is:io+cd+1]);
  1390.                    end;
  1391.             end;
  1392.             end;{case}
  1393.      end;{B}
  1394. {///////////////////////////////////////////////////////////////////////////}
  1395.   $C:begin
  1396.      case lnib(cm) of
  1397.      $0:begin
  1398.         inc(cd);
  1399.         EbIbi(shfts[rg(mem[is:io+cd])]);
  1400.         end;
  1401.      $1:begin
  1402.         inc(cd);
  1403.         EvIbi(shfts[rg(mem[is:io+cd])]);
  1404.         end;
  1405.      $2:begin
  1406.         inst:='ret';
  1407.         id:=2;
  1408.         o1st:=hxw(memw[is:io+cd+1]);
  1409.         end;
  1410.      $3:simple1('ret');
  1411.      $4:begin
  1412.         inst:='les';
  1413.         inc(cd);
  1414.         modrm(o2st);
  1415.         regs(o1st);
  1416.         dwordo2;
  1417.         memchk2;
  1418.         end;
  1419.      $5:begin
  1420.         inst:='lds';
  1421.         inc(cd);
  1422.         modrm(o2st);
  1423.         regs(o1st);
  1424.         dwordo2;
  1425.         memchk2;
  1426.         end;
  1427.      $6:begin
  1428.         inc(cd);
  1429.         EbIbi('mov');
  1430.         end;
  1431.      $7:begin
  1432.         inc(cd);
  1433.         EvIvi('mov');
  1434.         end;
  1435.      $8:begin
  1436.         inst:='enter';
  1437.         id:=3;
  1438.         o1st:=hxw(memw[is:io+cd+1]);
  1439.         o2st:=hxb(mem [is:io+cd+3]);
  1440.         end;
  1441.      $9:simple1('leave');
  1442.      $A:begin
  1443.         inst:='retf';
  1444.         id:=2;
  1445.         o1st:=hxw(memw[is:io+cd+1]);
  1446.         end;
  1447.      $B:simple1('retf');
  1448.      $C:simple1('int3');
  1449.      $D:begin
  1450.         inst:='int';
  1451.         id:=1;
  1452.         o1st:=hxb(mem[is:io+cd+1]);
  1453.         end;
  1454.      $E:simple1('into');
  1455.      $F:width1('iret','iretd');
  1456.         end;
  1457.      end;{C}
  1458. {///////////////////////////////////////////////////////////////////////////}
  1459.   $D:begin
  1460.      case lnib(cm) of
  1461.      $0:begin
  1462.         inc(cd);
  1463.         Ebi(shfts[rg(mem[is:io+cd])]);
  1464.         o2st:= '1';
  1465.         end;
  1466.      $1:begin
  1467.         inc(cd);
  1468.         Evi(shfts[rg(mem[is:io+cd])]);
  1469.         o2st:= '1';
  1470.         end;
  1471.      $2:begin
  1472.         inc(cd);
  1473.         Ebi(shfts[rg(mem[is:io+cd])]);
  1474.         o2st:='cl';
  1475.         end;
  1476.      $3:begin
  1477.         inc(cd);
  1478.         Evi(shfts[rg(mem[is:io+cd])]);
  1479.         o2st:='cl';
  1480.         end;
  1481.      $4:begin
  1482.         inst:='aam';
  1483.         inc(cd);
  1484.         if(mem[is:io+cd]<>$0A)
  1485.           then begin
  1486.                inst:='';
  1487.                dec(cd);
  1488.                end;
  1489.         end;
  1490.      $5:begin
  1491.         inst:='aad';
  1492.         inc(cd);
  1493.         if(mem[is:io+cd]<>$0A)
  1494.           then begin
  1495.                inst:='';
  1496.                dec(cd);
  1497.                end;
  1498.         end;
  1499.      $6:begin
  1500.         end;
  1501.      $7:simple1('xlat');
  1502.      $8..$F:begin
  1503.             inst:='esc';
  1504.             end;
  1505.         end;{case}
  1506.      end;{D}
  1507. {///////////////////////////////////////////////////////////////////////////}
  1508.   $E:begin
  1509.      case lnib(cm) of
  1510.      0..3:Jb(loops[lnib(mem[is:io+cd])]);
  1511.      $4:ALIb('in');
  1512.      $5:eAXIb('in');
  1513.      $6:begin
  1514.         ALIb('out');
  1515.         swapp;
  1516.         end;
  1517.      $7:begin
  1518.         eAXIb('out');
  1519.         swapp;
  1520.         end;
  1521.      $8:Jv('call');
  1522.      $9:Jv('jmp');
  1523.      $A:Ap('jmp');
  1524.      $B:Jb('jmp');
  1525.      $C:simple3('in','al','dx');
  1526.      $D:begin
  1527.         simple3('in','','dx');
  1528.         eAX1;
  1529.         end;
  1530.      $E:simple3('out','dx','al');
  1531.      $F:begin
  1532.         simple2('out','dx');
  1533.         eAX2;
  1534.         end;
  1535.         end;{case}
  1536.      end;{E}
  1537. {///////////////////////////////////////////////////////////////////////////}
  1538.   $F:begin
  1539.      case lnib(cm) of
  1540.      $0:begin
  1541.         legop('lock ');
  1542.         goto again;
  1543.         end;
  1544.      $2:begin
  1545.         legop('repne ');
  1546.         goto again;
  1547.         end;
  1548.      $3:begin
  1549.         legop('rep ');
  1550.         goto again;
  1551.         end;
  1552.      $4:simple1('hlt');
  1553.      $5:simple1('cmc');
  1554.      $6:begin
  1555.         inc(cd);
  1556.         case rg(mem[is:io+cd]) of
  1557.          0,1:EbIbi('test');
  1558.            2:Ebi('not');
  1559.            3:Ebi('neg');
  1560.            4:Ebi('mul');
  1561.            5:Ebi('imul');
  1562.            6:Ebi('div');
  1563.            7:Ebi('idiv');
  1564.              end;
  1565.         end;
  1566.      $7:begin
  1567.         inc(cd);
  1568.         case rg(mem[is:io+cd]) of
  1569.          0,1:EvIvi('test');
  1570.            2:Evi('not');
  1571.            3:Evi('neg');
  1572.            4:Evi('mul');
  1573.            5:Evi('imul');
  1574.            6:Evi('div');
  1575.            7:Evi('idiv');
  1576.              end;
  1577.         end;
  1578.      $8:simple1('clc');
  1579.      $9:simple1('stc');
  1580.      $A:simple1('cli');
  1581.      $B:simple1('sti');
  1582.      $C:simple1('cld');
  1583.      $D:simple1('std');
  1584.      $E:begin
  1585.         inc(cd);
  1586.         if(rg(mem[is:io+cd])=0)then Ebi('inc')
  1587.           else if(rg(mem[is:io+cd])=1)then Ebi('dec')
  1588.             else begin
  1589.                  inst:='';
  1590.                  o1st:='';
  1591.                  o2st:='';
  1592.                  dec(cd);
  1593.                  end;
  1594.         end;
  1595.      $F:begin
  1596.         inc(cd);
  1597.         case rg(mem[is:io+cd]) of
  1598.            0:Evi('inc');
  1599.            1:Evi('dec');
  1600.            2:Evi('call');
  1601.            3:eP('call');
  1602.            4:Evi('jmp');
  1603.            5:eP('jmp');
  1604.            6:Evi('push');
  1605.            7:dec(cd);
  1606.              end;
  1607.         end;
  1608.         end;{case}
  1609.         end;{F}
  1610. {///////////////////////////////////////////////////////////////////////////}
  1611.         end;{case hnib}
  1612.  
  1613.    if(inst='')then
  1614.      if((pist<>'')or(list<>''))
  1615.        then begin
  1616.             inst:=list+pist;
  1617.             list:='';
  1618.             pist:='';
  1619.             dec(cd);
  1620.             end
  1621.        else begin
  1622.             inst:='db';
  1623.             o1st:=hxb(mem[is:io]);
  1624.             end;
  1625.    io:=io+cd+ad+id+1;
  1626. end;
  1627. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  1628. {▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒}
  1629. {
  1630.  returns previous io(instruction offset)
  1631. }
  1632. function oldio:word;
  1633. begin
  1634.   oldio:=io-(cd+ad+id+1);
  1635. end;
  1636.  
  1637. {
  1638.  Disassembly
  1639.    to global string dstr
  1640.    from global is:io
  1641. }
  1642. procedure disasnext;
  1643. var
  1644.    t:word;
  1645. begin
  1646.   if fulldisas then dstr:=hxw(is)+':'
  1647.                else dstr:='';
  1648.   dstr:=dstr+hxw(io)+' ';
  1649.   onebyte;
  1650.   if(fulldisas)
  1651.     then begin
  1652.          t:=io-(cd+ad+id+1);
  1653.          while(t<>io) do
  1654.            begin
  1655.            dstr:=dstr+hxb(mem[is:t]);
  1656.            inc(t);
  1657.            end;
  1658.          for t:=1 to 29-length(dstr) do dstr:=dstr+' ';
  1659.          end;
  1660.   dstr:=dstr+list+inst+' '+pist+o1st;
  1661.   if(length(o2st)<>0) then dstr:=dstr+','+o2st;
  1662. end;
  1663.  
  1664. {
  1665.  inits is:io and does one instruction disassembly
  1666. }
  1667. procedure disas(s,o:word);
  1668. begin
  1669.   is:=s;
  1670.   io:=o;
  1671.   disasnext;
  1672. end;
  1673.  
  1674. {
  1675.  writeln disassembly
  1676.   p is pointer to start
  1677.   c is number of lines/instructions
  1678. }
  1679. procedure disasptr(p:pointer;c:byte);
  1680. var x:byte;
  1681. begin
  1682.   if c=0 then c:=24;
  1683.   disas(seg(p^),ofs(p^));
  1684.   writeln(dstr);
  1685.   for x:=2 to c do
  1686.     begin
  1687.     disasnext;
  1688.     writeln(dstr);
  1689.     end;
  1690. end;
  1691.  
  1692. {
  1693.  writeln disassembly
  1694.   p is pointer to start
  1695.   c is number of lines/instructions
  1696.   l is string max length
  1697. }
  1698. procedure disasptrl(p:pointer;c:byte;l:byte);
  1699. var
  1700.    x:byte;
  1701.    t:byte;
  1702. begin
  1703.    if c=0 then c:=24;
  1704.    disas(seg(p^),ofs(p^));
  1705.    if(l<>0)
  1706.      then if(dstr[0]>chr(l))
  1707.             then dstr[0]:=chr(l);
  1708.    for t:=1 to l-length(dstr) do dstr:=dstr+' ';
  1709.    writeln(dstr);
  1710.  
  1711.    for x:=2 to c do
  1712.      begin
  1713.      disasnext;
  1714.      if(l<>0)
  1715.        then if(dstr[0]>chr(l))
  1716.               then dstr[0]:=chr(l);
  1717.      for t:=1 to l-length(dstr) do dstr:=dstr+' ';
  1718.      write(dstr);
  1719.      if(x<>c) then writeln;
  1720.      end;
  1721. end;
  1722.  
  1723.  
  1724. end.